package com.jzcn.admin.exception;


import com.jzcn.common.exceptions.BusinessException;
import com.jzcn.common.response.ResponseResult;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * 处理其他异常
     * @param exception
     * @return
     */
    @ExceptionHandler({Exception.class})
    public ResponseResult handleUncaughtException(Exception exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure("系统异常,请稍后再试!");
    }

    /**
     * 处理自定义的业务异常
     * @param exception
     * @return
     */
    @ExceptionHandler({BusinessException.class})
    public ResponseResult handleUncaughtException(BusinessException exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure(exception.getMessage());
    }

    /**
     * 捕捉404异常
     * @param exception
     * @return
     */
    @ExceptionHandler({NoHandlerFoundException.class})
    public ResponseResult noHandlerFoundException(NoHandlerFoundException exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure(exception.getMessage());
    }

    /**
     * 单独捕捉Shiro(UnauthenticatedException)异常
     * 该异常为以游客身份访问有权限管控的请求无法对匿名主体进行授权，而授权失败所抛出的异常
     * @param e
     * @return
     */
    @ExceptionHandler(UnauthenticatedException.class)
    public ResponseResult handle401(UnauthenticatedException e) {
        return ResponseResult.failure(ResponseResult.NO_LOGIN,"登录超时，请重新登录");
    }

    /**
     * 身份验证出错异常
     * @param exception
     * @return
     */
    @ExceptionHandler({AuthenticationException.class})
    public ResponseResult handleAuthenticationException(AuthenticationException exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure(ResponseResult.UNAUTHORIZED,exception.getMessage());
    }

    /**
     * 权限认证异常
     * @param exception
     * @return
     */
    @ExceptionHandler({AuthorizationException.class})
    public ResponseResult handleAuthorizationException(AuthorizationException exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure(ResponseResult.UNAUTHORIZED,exception.getMessage());
    }


    /**
     * 捕捉UnauthorizedException自定义异常
     * @param exception
     * @return
     */
    @ExceptionHandler({UnauthorizedException.class})
    public ResponseResult handleUnauthorizedException(UnauthorizedException exception) {
        log.error(exception.getMessage(), exception);
        return ResponseResult.failure(ResponseResult.UNAUTHORIZED,"您没有该功能的操作权限!");
    }

    /**
     * 处理空指针的异常
     * @param req
     * @param exception
     * @return
     */
    @ExceptionHandler({NullPointerException.class})
    public ResponseResult exceptionHandler(HttpServletRequest req, NullPointerException exception){
        log.error(exception.getMessage(),exception);
        return ResponseResult.failure("发生空指针异常！原因是:"+exception.getMessage());
    }
}
